The mata magic

The mata magic is used to execute Mata code. Mata is a matrix programming language that can be used by those who want to do matrix computations interactively and by those who want to add new features to Stata. You can read about all of Mata’s features here.

The mata magic can be used as both a line magic and a cell magic command. When used as a line magic, it allows you to either execute a single-line Mata statement or enter Mata’s interactive environment. You can type %%mata? to view its documentation.

[23]:
%%mata?

Docstring:

Execute one line or a block of Mata code.

When the %mata line magic command is used, one line of Mata code can be specified and executed. This is similar to specifying mata: istmt within Stata. When the %%mata cell magic command is used, a block of Mata code can be specified. The code is executed just as it would be in a do-file.

Cell magic syntax:

%%mata [-m ARRAYLIST] [-outm MATLIST] [-qui] [-c]

  Execute a block of Mata code. This is equivalent to running a
  block of Mata code within a do-file. You do not need to
  explicitly place the code within the mata[:] and end block.

  Optional arguments:

    -m ARRAYLIST      Load multiple NumPy arrays into Mata's
                      interactive environment. The array names
                      should be separated by commas. Each array is
                      stored in Mata as a matrix with the same name.

    -outm MATLIST     Save Mata matrices as NumPy arrays when the
                      cell completes. The matrix names should be
                      separated by commas. Each matrix is stored
                      in Python as a NumPy array.

    -qui              Run Mata code but suppress output.

    -c                This argument specifies that Mata code be
                      executed in mata: mode. This means that
                      if Mata encounters an error, it will stop
                      execution and return control to Python. The
                      error will then be thrown as a Python SystemError
                      exception.

Line magic syntax:

%mata [-c]

  Enter Mata's interactive environment. This is equivalent to
  typing mata or mata: in the Stata Command window.

  Optional argument:

    -c                Enter interactive Mata environment in mata:
                      mode. The default is to enter in mata mode.

%mata istmt

  Run a single-line Mata statement. This is equivalent to executing
  mata: istmt within Stata.

%%mata cell magic

The %%mata magic is used to execute multiple lines of Mata code at once. This is similar to executing Mata code within a mata[:] and end block in a do-file. See [M-3] mata for more information about how to invoke Mata.

[24]:
%%mata
a = 3

/* create an NxN identity matrix */
real matrix id(real scalar n)
{
    real scalar i
    real matrix res

    res = J(n, n, 0)
    for (i=1; i<=n; i++) {
        res[i,i] = 1
    }
    return(res)
}

B = id(a)
B

. mata
------------------------------------------------- mata (type end to exit) -----
: a = 3

:
: /* create an NxN identity matrix */
: real matrix id(real scalar n)
> {
>     real scalar i
>     real matrix res
>
>     res = J(n, n, 0)
>     for (i=1; i<=n; i++) {
>         res[i,i] = 1
>     }
>     return(res)
> }

:
: B = id(a)

: B
[symmetric]
       1   2   3
    +-------------+
  1 |  1          |
  2 |  0   1      |
  3 |  0   0   1  |
    +-------------+

: end
-------------------------------------------------------------------------------

.

Arguments

By default, code is executed in mata mode. This means that even if an error occurs, Mata will continue execution until the last Mata statement in the block has run to completion.

In the following cell, we specify an undefined number, unknown, as the dimension of the identity matrix; although this causes Mata to return an error, the following statement is still executed.

[25]:
%%mata
C = id(unknown)
display("This line will still be printed.")

. mata
------------------------------------------------- mata (type end to exit) -----
: C = id(unknown)
                 <istmt>:  3499  unknown not found
r(3499);

: display("This line will still be printed.")
This line will still be printed.

: end
-------------------------------------------------------------------------------

.

-c

This argument specifies that Mata code be executed in mata: mode. This means that if Mata encounters an error, it will stop execution and return control to Python. The error will then be thrown as a Python SystemError exception.

For example, when we add the -c argument to the code above, we see that Python raises an exception and the error code is returned after having exited the Mata environment.

[26]:
%%mata -c
C = id(unknown)
display("This line will not be printed.")
Exception in thread Stata:
Traceback (most recent call last):
  File "c:\users\zxx\appdata\local\programs\python\python37\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:/Program Files/Stata18/utilities\pystata\core\stout.py", line 176, in run
    raise SystemError(output)
SystemError:
. mata:
------------------------------------------------- mata (type end to exit) -----
: C = id(unknown)
                 <istmt>:  3499  unknown not found
(1 line skipped)
-------------------------------------------------------------------------------
r(3499);
r(3499);


-qui

The -qui argument specifies to execute the block of Mata code but suppress the output.

[27]:
%%mata -qui
/*no output*/
C = id(5)
C

-m ARRAYLIST

This argument loads one or multiple NumPy arrays into Mata’s interactive environment, storing each array into a matrix with the same name. To load multiple arrays, specify a list with array names separated by commas. There should be no whitespace between the names unless you enclose the list within single quotes () or double quotes ().

-outm MATLIST

This argument saves one or multiple Mata matrices as NumPy arrays when the cell completes execution; each matrix is stored as a separate NumPy array in Python. To export multiple matrices, specify a list with matrix names separated by commas. There should be no whitespace between the names unless you enclose the list within single quotes () or double quotes ().

In the following, we create a 5x5 NumPy array with random values and a 4x4 identity NumPy array, and we load the two arrays into Mata.

[28]:
import numpy as np

np.random.seed(17)
npa = np.random.random((5,5))
npb = np.identity(4)
[29]:
%%mata -m npa,npb
npa
npb

. mata
------------------------------------------------- mata (type end to exit) -----
: npa
                 1             2             3             4             5
    +-----------------------------------------------------------------------+
  1 |  .2946650027   .5305867556   .1915207869   .0679003582     .78698546  |
  2 |  .6563335218    .637520896   .5756028938   .0390629162   .3578136045  |
  3 |  .9456831868   .0600446803   .8640421035   .8772905261   .0511936656  |
  4 |  .6524186155   .5517513686   .5975132532   .4835286243   .2829881609  |
  5 |  .2977257183   .5615089053    .396047436   .7887007097   .4184843853  |
    +-----------------------------------------------------------------------+

: npb
[symmetric]
       1   2   3   4
    +-----------------+
  1 |  1              |
  2 |  0   1          |
  3 |  0   0   1      |
  4 |  0   0   0   1  |
    +-----------------+

: end
-------------------------------------------------------------------------------

.

Within Mata, we calculate the singular value decomposition of npa and return the result in U, s, and Vt. Then we push those Mata matrices to Python as NumPy arrays.

[30]:
%%mata -outm U,s,Vt
U = s = Vt = .
svd(npa, U, s, Vt)

. mata
------------------------------------------------- mata (type end to exit) -----
: U = s = Vt = .

: svd(npa, U, s, Vt)

: end
-------------------------------------------------------------------------------

.
[31]:
U, s, Vt
[31]:
(array([[-0.29776638,  0.66038134, -0.08825852,  0.67569317, -0.10431127],
        [-0.41723241,  0.31691857,  0.61847411, -0.3391098 ,  0.47746629],
        [-0.56518202, -0.6740881 ,  0.10325862,  0.44410707,  0.13520756],
        [-0.47965858,  0.02588292,  0.08960879, -0.348452  , -0.79988073],
        [-0.43330038,  0.09162108, -0.76877053, -0.33135087,  0.32102154]]),
 array([[2.45473309],
        [1.01798709],
        [0.59358903],
        [0.29611096],
        [0.02692625]]),
 array([[-0.5450739 , -0.39347486, -0.50666998, -0.45056571, -0.297234  ],
        [-0.187344  ,  0.56747614, -0.2178739 , -0.44143434,  0.63288209],
        [ 0.51744255, -0.04812796,  0.29883434, -0.76525509, -0.23456257],
        [ 0.23818892, -0.70691335, -0.07257898, -0.02559534,  0.66152606],
        [-0.58593166, -0.14527762,  0.77540108, -0.12591977,  0.13592601]]))

%mata line magic

The %mata line magic can be run in two modes. The first mode is used for evaluating Mata code in an interactive environment. This is the same as typing mata or mata: in Stata’s Command window to enter Mata’s interactive environment. Within this environment, you can type Mata statements one by one and exit the environment with end.

%mata [-c]

If no Mata statement is specified and the -c argument is not specified, %mata will enter the interactive environment in mata mode. This means that even if an error occurs, you will stay in the environment until end is typed.

When -c is specified, %mata will enter the interactive environment in mata: mode. This means that if an error occurs, a Python SystemError exception is thrown and this interactive environment is ended automatically.

[32]:
%mata
. mata
------------------------------------------------- mata (type end to exit) ---
: B = Hilbert(5)

: B
[symmetric]
                 1             2             3             4             5
    +-----------------------------------------------------------------------+
  1 |            1                                                          |
  2 |           .5   .3333333333                                            |
  3 |  .3333333333           .25            .2                              |
  4 |          .25            .2   .1666666667   .1428571429                |
  5 |           .2   .1666666667   .1428571429          .125   .1111111111  |
    +-----------------------------------------------------------------------+

: end
-----------------------------------------------------------------------------

The second mode of the %mata line magic is to evaluate a single-line Mata statement in Stata.

%mata istmt

This is equivalent to executing mata: istmt in Stata.

[33]:
%mata invsym(B)
[symmetric]
             1         2         3         4         5
    +---------------------------------------------------+
  1 |       25                                          |
  2 |     -300      4800                                |
  3 |     1050    -18900     79380                      |
  4 |    -1400     26880   -117600    179200            |
  5 |      630    -12600     56700    -88200     44100  |
    +---------------------------------------------------+